package com.se.utils;

import com.se.common.*;
import com.se.mainView.MainViewController;
import com.se.optionView.AddFriendController;
import com.se.optionView.CreateGroupController;
import com.se.optionView.JoinGroupController;
import javafx.application.Platform;
import org.json.JSONObject;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static com.se.common.Constant.*;

/**
 * 客户端连接线程类 - 负责维持与服务端的连接和通信
 */

public class ClientConnectThread extends Thread{
    Socket socket;
    private volatile boolean running = true;

    public ClientConnectThread(Socket socket){
        this.socket = socket;
    }

    public Socket getSocket() {
        return socket;
    }

    public void close(){
        try {
            if(socket != null && !socket .isClosed()) {
                running = false;
                socket.close();
            }
        } catch (IOException e) {
            /*
            无需处理
             */
            e.printStackTrace();
        }
    }

    @Override
    public void run() {


        while(running && !socket.isClosed()){
            try {
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                Message msg = (Message) ois.readObject();

                handleMessage(msg);
            } catch (IOException | ClassNotFoundException e) {
                /*
                 JavaFX Application退出时会报一次错，影响不大，以后看能不能修
                 后续优化异常处理，当前只是简单捕获并抛出运行时异常，正式环境需要更友好的错误提示
                */
                e.printStackTrace();
                close();
            }
        }
    }

    private void handleMessage(Message msg) {
        Message message = new Message();

        if(MessageType.MESSAGE_USER_LIST_REQUEST.equals(msg.getMsgType())) {
            User user = new User();
            JSONObject json = new JSONObject(msg.getContent());
            user.setUserName(json.getString(USERNAME));
            user.setStatus(json.getString(STATUS));
            user.setNotify(json.getBoolean(NOTIFY));
            ServiceUtils.addUserList(user);
            return;
        }

        if(MessageType.MESSAGE_GET_GROUP_MEMBERS.equals(msg.getMsgType())) {
            User user = new User();
            JSONObject json = new JSONObject(msg.getContent());
            user.setUserName(json.getString(USERNAME));
            user.setStatus(json.getString(STATUS));
            MainViewController.getInstance().addMemberList(user);
            return;
        }

        if(MessageType.MESSAGE_USER_LIST_UPDATE.equals(msg.getMsgType())) {
            User user = new User();
            JSONObject json = new JSONObject(msg.getContent());
            user.setUserName(json.getString(USERNAME));
            user.setStatus(json.getString(STATUS));
            user.setNotify(json.getBoolean(NOTIFY));
            ServiceUtils.addUserList(user);
            return;
        }

        if(MessageType.MESSAGE_COMMON.equals(msg.getMsgType())) {
            if(msg.getSendUser().equals(ServiceUtils.getChatUser().getUserName())
                    || msg.getSendUser().equals(ServiceUtils.getSpeaker().getUserName())) {

                ServiceUtils.addMessageList(msg);
                message.setMsgType(MessageType.MESSAGE_REMOVE_NOTIFY);
                message.setSendUser(msg.getSendUser());
                message.setReceiveUser(msg.getReceiveUser());
                try {
                    ClientUtils.sendMessage(socket, message);
                } catch (IOException e) {
                    /*
                    后续优化异常处理
                     */
                    e.printStackTrace();
                }
            }
            else {
                ServiceUtils.setNotify(msg.getSendUser(), true);
                ServiceUtils.insertMessageIntoMessageTables(
                        new UsernameOrGroupId(msg.getSendUser()), msg);
            }

            return;
        }

        if(MessageType.MESSAGE_GROUP_LIST_REQUEST.equals(msg.getMsgType())) {
            Group group = new Group(msg.getContent());
            ServiceUtils.addGroupList(group);
            return;
        }

        if(MessageType.MESSAGE_GROUP_COMMON.equals(msg.getMsgType())) {
            int groupId = Integer.parseInt(msg.getReceiveUser());
            if(groupId == ServiceUtils.getChatGroup().getGroupId()
                    || msg.getSendUser().equals(ServiceUtils.getSpeaker().getUserName())) {

                ServiceUtils.addMessageList(msg);
                message.setMsgType(MessageType.MESSAGE_REMOVE_GROUP_NOTIFY);
                message.setSendUser(msg.getReceiveUser());
                message.setReceiveUser(ServiceUtils.getSpeaker().getUserName());
                try {
                    ClientUtils.sendMessage(socket, message);
                } catch (IOException e) {
                    /*
                    后续优化异常处理
                     */
                    e.printStackTrace();
                }
            }
            else {
                ServiceUtils.setGroupNotify(groupId, true);
                ServiceUtils.insertMessageIntoMessageTables(
                        new UsernameOrGroupId(groupId), msg);
            }
            return;
        }

        //图片直接存
        //这里有一个问题，如果图片太大会把线程阻塞，以后可以考虑加上体积限制（如1MB?
        if(MessageType.MESSAGE_FILE_IMAGE.equals(msg.getMsgType())
                || MessageType.MESSAGE_FILE.equals(msg.getMsgType())) {
            FileMessage fileMessage = (FileMessage) msg;
            if (fileMessage.getFileContent() != null) {
                Path path;
                if(fileMessage.getSendUser().equals(ServiceUtils.getSpeaker().getUserName())) {//如果文件是自己发的
                    path = Path.of(fileMessage.getFilePath());
                }
                else {
                    path = Path.of(ServiceUtils.FILE_STORAGE_PATH);
                    path = path.resolve(fileMessage.getFileName());
                }
                boolean exists = Files.exists(Paths.get(path.toString()));

                //如果文件不存在才下载
                if(!exists) {
                    Path finalPath = path;

                    //涉及到文件IO的操作，尽量开新线程进行
                    new Thread(() -> {
                        try (FileOutputStream fos = new FileOutputStream(finalPath.toString())) {
                            fos.write(fileMessage.getFileContent());
                            //考虑该线程没执行完图片就已经被添加到消息列表的情况，这里下载完了刷新一下
                            MainViewController.getInstance().refreshMessageList();
                        } catch (Exception e) {
                    /*
                    异常处理待优化
                     */
                            e.printStackTrace();
                        }
                    }).start();
                }
            }

            if(!ServiceUtils.isInteger(msg.getReceiveUser())) {//如果和跟人用户在聊天
                if(msg.getSendUser().equals(ServiceUtils.getChatUser().getUserName())
                        || msg.getSendUser().equals(ServiceUtils.getSpeaker().getUserName())) {

                    if(!MessageType.MESSAGE_FILE.equals(msg.getMsgType())
                            || fileMessage.getFileContent() == null) {
                        //如果是用户下载的文件就不需要添加到消息列表
                        ServiceUtils.addMessageList(msg);
                    }
                    message.setMsgType(MessageType.MESSAGE_REMOVE_NOTIFY);
                    message.setSendUser(msg.getSendUser());
                    message.setReceiveUser(msg.getReceiveUser());
                    try {
                        ClientUtils.sendMessage(socket, message);
                    } catch (IOException e) {
                    /*
                    后续优化异常处理
                     */
                        e.printStackTrace();
                    }
                }
                else {
                    ServiceUtils.setNotify(msg.getSendUser(), true);
                    ServiceUtils.insertMessageIntoMessageTables(
                            new UsernameOrGroupId(msg.getSendUser()), msg);
                }
            }
            else {//如果和群组聊天
                int groupId = Integer.parseInt(msg.getReceiveUser());
                if(groupId == ServiceUtils.getChatGroup().getGroupId()
                        || msg.getSendUser().equals(ServiceUtils.getSpeaker().getUserName())) {

                    if(!MessageType.MESSAGE_FILE.equals(msg.getMsgType())
                            || fileMessage.getFileContent() == null) {
                        //如果是用户下载的文件就不需要添加到消息列表
                        ServiceUtils.addMessageList(msg);
                    }

                    message.setMsgType(MessageType.MESSAGE_REMOVE_GROUP_NOTIFY);
                    message.setSendUser(msg.getReceiveUser());
                    message.setReceiveUser(ServiceUtils.getSpeaker().getUserName());
                    try {
                        ClientUtils.sendMessage(socket, message);
                    } catch (IOException e) {
                    /*
                    后续优化异常处理
                     */
                        e.printStackTrace();
                    }
                }
                else {
                    ServiceUtils.setGroupNotify(groupId, true);
                    ServiceUtils.insertMessageIntoMessageTables(
                            new UsernameOrGroupId(groupId), msg);
                }
            }
            return;
        }

        if(MessageType.MESSAGE_CREATE_GROUP.equals(msg.getMsgType())) {
            Group group = new Group(msg.getContent());
            ServiceUtils.addGroupList(group);
            Platform.runLater(() -> {
                CreateGroupController.getInstance().btnCancelOnClick();
                ClientUtils.information_Alert("创建成功！");
            });
            return;
        }

        if(MessageType.MESSAGE_JOIN_GROUP.equals(msg.getMsgType())) {
            Platform.runLater(() -> {
                JoinGroupController.getInstance().btnCancelOnClick();
                ClientUtils.information_Alert("加入成功！");
            });
            return;
        }

        if(MessageType.MESSAGE_ALREADY_IN_GROUP.equals(msg.getMsgType())) {
            Platform.runLater(() -> ClientUtils.information_Alert("你已经在该群组中！"));
            return;
        }

        if(MessageType.MESSAGE_GROUP_UPDATE.equals(msg.getMsgType())) {
            Group group = new Group(msg.getContent());
            ServiceUtils.addGroupList(group);
            System.out.println("更新群组: " + group.getGroupName());
            Platform.runLater(() -> {
                MainViewController.getInstance().refreshGroupList();
                String groupAI = group.getGroupAI();
                if(groupAI != null && !groupAI.isEmpty()) {
                    String aiName = groupAI.split(" ")[1];
                    AIUser aiUser = new AIUser();
                    aiUser.setAI_name(aiName);
                    MainViewController.getInstance().addAIUser(aiUser);
                }
            });
            return;
        }

        if(MessageType.MESSAGE_GROUP_NOT_EXIST.equals(msg.getMsgType())) {
            Platform.runLater(() -> ClientUtils.information_Alert("群组不存在！"));
            return;
        }

        if(MessageType.MESSAGE_SENTENCE_EXPLAIN.equals(msg.getMsgType())) {
            System.out.println(msg.getContent());
            if(AIErrorType.UNAUTHORIZED_ERROR.equals(msg.getContent())) {
                Platform.runLater(() -> ClientUtils.information_Alert("APIKEY无效！"));
                return;
            }
            else if(AIErrorType.NOT_ENOUGH_TOKEN.equals(msg.getContent())) {
                Platform.runLater(() -> ClientUtils.information_Alert("API余额不足！"));
                return;
            }
            else if(AIErrorType.SERVER_ERROR.equals(msg.getContent())) {
                Platform.runLater(() -> ClientUtils.information_Alert("AI服务器异常！"));
                return;
            }
            else if(AIErrorType.SERVER_BUSY.equals(msg.getContent())) {
                Platform.runLater(() -> ClientUtils.information_Alert("AI服务器繁忙！"));
                return;
            }
            else if(AIErrorType.UNKNOWN_ERROR.equals(msg.getContent())) {
                Platform.runLater(() -> ClientUtils.information_Alert("发生未知错误"));
                return;
            }

            ServiceUtils.addAIMessage(msg);
            return;
        }

        if(MessageType.MESSAGE_CLOSE_FILE_CONNECTION_REQUEST.equals(msg.getMsgType())) {
            try {
                ServiceUtils.closeFileConnection();
            } catch (IOException e) {
                /*
                无需额外处理
                 */
                e.printStackTrace();
            }
        }

        if(MessageType.MESSAGE_SEARCH_FRIEND.equals(msg.getMsgType())) {
            JSONObject json = new JSONObject(msg.getContent());
            User item = new User(json.getString(USERNAME), null);
            item.setStatus(json.getString(STATUS));
            AddFriendController.getInstance().addResult(item);
            return;
        }

        if(MessageType.MESSAGE_ADD_FRIEND.equals(msg.getMsgType())) {
            ServiceUtils.addFriendRequest(msg.getSendUser());
            return;
        }

        if(MessageType.MESSAGE_REFRESH_USER_LIST.equals(msg.getMsgType())) {

        }
    }
}
